#ifndef SC_USB_H
#define SC_USB_H

#include "common.h"

#include <stdbool.h>
#include <libusb-1.0/libusb.h>

#include "util/thread.h"

/* 自定义USB上下文 */
struct sc_usb {
    // libusb环境上下文
    libusb_context *context;
    // 一个设备句柄
    libusb_device_handle *handle;

    // 断开事件回调
    const struct sc_usb_callbacks *cbs;
    void *cbs_userdata;

    bool has_callback_handle;
    // 热插拨回调
    libusb_hotplug_callback_handle callback_handle;

    bool has_libusb_event_thread;
    sc_thread libusb_event_thread;

    atomic_bool stopped; // only used if cbs != NULL

    // atomic_flag 一种简单的原子布尔类型，只支持两种操作，test-and-set 和 clear。
    atomic_flag disconnection_notified;
};

/* USB断开回调 */
struct sc_usb_callbacks {
    // USB设备断开连接事件    
    void (*on_disconnected)(struct sc_usb *usb, void *userdata);
};

/* 自定义USB设备 */
struct sc_usb_device {
    libusb_device *device;
    char *serial;
    char *manufacturer;
    char *product;
    uint16_t vid;
    uint16_t pid;
    bool selected;
};

/*
销毁一个USB设备
@param usb_device
*/
void
sc_usb_device_destroy(struct sc_usb_device *usb_device);

/**
 * Move src to dst
 *
 * After this call, the content of src is undefined, except that
 * sc_usb_device_destroy() can be called.
 *
 * This is useful to take a device from a list that will be destroyed, without
 * making unnecessary copies.
 */
void
sc_usb_device_move(struct sc_usb_device *dst, struct sc_usb_device *src);

/*
这个方法未实现，也没有调用的地方
*/
void
sc_usb_devices_destroy_all(struct sc_usb_device *usb_devices, size_t count);

/* 
初始化USB连接
@param usb usb上下文
@return 成功返回True,否则返回false 
*/
bool
sc_usb_init(struct sc_usb *usb);

/* 
销毁并清理USB连接 
@param usb
*/
void
sc_usb_destroy(struct sc_usb *usb);

/*
根据android设备的序列号选择设备
@param usb USB上下文
@param serial android设备序列号
@param out_device 回写选中的USB设备
@return 执行成功返回true,否则返回false
*/
bool
sc_usb_select_device(struct sc_usb *usb, const char *serial,
                     struct sc_usb_device *out_device);

/*

@param usb USB上下文
@param device USB设备
@param cbs 回调事件，目前仅用于otg连接中
@param cbs_userdata 回调事件用到的数据，目前全部传NULL
@return 成功返回true,否则返回false
*/
bool
sc_usb_connect(struct sc_usb *usb, libusb_device *device,
               const struct sc_usb_callbacks *cbs, void *cbs_userdata);

/*
libusb_close 的简单封装
@param usb
*/
void
sc_usb_disconnect(struct sc_usb *usb);

// A client should call this function with the return value of a libusb call
// to detect disconnection immediately
bool
sc_usb_check_disconnected(struct sc_usb *usb, int result);

void
sc_usb_stop(struct sc_usb *usb);

void
sc_usb_join(struct sc_usb *usb);

#endif
